﻿using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
using System.Collections;
using System.Drawing;
using System.Collections.Generic;

namespace V5_EaspLibs.Utility {
    /// <summary>
    /// 采集分类
    /// </summary>
    public class NewsCollection {
        public NewsCollection() {
        }

        /// <summary>
        /// 得到页面的内容
        /// </summary>
        /// <param name="url">地址 http://www.qbzw.com</param>
        /// <param name="timeout">返回超时 单位 毫秒</param>
        /// <param name="EnCodeType">编码 gb2312 等</param>
        /// <returns></returns>
        public string GetHttpPage(string url, int timeout, Encoding EnCodeType) {
            string strResult = string.Empty;
            if (url.Length < 10)
                return "$UrlIsFalse$";
            try {
                WebClient MyWebClient = new WebClient();
                MyWebClient.Credentials = CredentialCache.DefaultCredentials;
                MyWebClient.Encoding = EnCodeType;
                strResult = MyWebClient.DownloadString(url);
            }
            catch (Exception) {
                strResult = "$GetFalse$";
            }
            return strResult;
        }

        public string GetHttp(string sUrl) {
            WebClient WC = new WebClient();
            WC.Credentials = CredentialCache.DefaultCredentials;
            Byte[] PageData = WC.DownloadData(sUrl);
            string HtmlCode = Encoding.Default.GetString(PageData);
            WC.Dispose();
            return HtmlCode;
        }
        /// <summary>
        /// 获取内容
        /// </summary>
        /// <param name="pageStr">截取的字符串</param>
        /// <param name="strStart">开始字符</param>
        /// <param name="strEnd">结束字符</param>
        /// <param name="inStart">是否包含开始字符</param>
        /// <param name="inEnd">是否包含结束字符</param>
        /// <returns>返回匹配的字符串</returns>
        public string GetBody(string pageStr, string strStart, string strEnd, bool inStart, bool inEnd) {
            pageStr = pageStr.Trim();
            int start = pageStr.IndexOf(strStart);
            if (strStart.Length == 0 || start < 0)
                return "$StartFalse$";
            pageStr = pageStr.Substring(start + strStart.Length, pageStr.Length - start - strStart.Length);
            int end = pageStr.IndexOf(strEnd);
            if (strEnd.Length == 0 || end < 0)
                return "$EndFalse$";
            string strResult = pageStr.Substring(0, end);
            if (inStart)
                strResult = strStart + strResult;
            if (inEnd)
                strResult += strEnd;
            return strResult.Trim();
        }

        /// <summary>
        /// 截取字符
        /// </summary>
        /// <param name="sStr">字符</param>
        /// <param name="Patrn">表达式</param>
        /// <returns></returns>
        public string[] CutStr(string sStr, string Patrn) {
            string[] RsltAry;
            Regex tmpreg = new Regex(Patrn, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            MatchCollection sMC = tmpreg.Matches(sStr);
            if (sMC.Count != 0) {
                RsltAry = new string[sMC.Count];
                for (int i = 0; i < sMC.Count; i++) {
                    RsltAry[i] = sMC[i].Groups[1].Value;
                }
            }
            else {
                RsltAry = new string[1];
                RsltAry[0] = "";
            }
            return RsltAry;
        }

        /// <summary>
        /// 格式化地址
        /// </summary>
        /// <param name="BaseUrl"></param>
        /// <param name="theUrl"></param>
        /// <returns></returns>
        public string FormatUrl(string BaseUrl, string theUrl) {
            int pathLevel = 0;
            string hostName;
            theUrl = theUrl.ToLower();
            hostName = BaseUrl.Substring(0, BaseUrl.IndexOf("/", 8));
            BaseUrl = BaseUrl.Substring(0, BaseUrl.LastIndexOf("/"));
            if (theUrl.StartsWith("./")) {
                theUrl = theUrl.Remove(0, 1);
                theUrl = BaseUrl + theUrl;
            }
            else if (theUrl.StartsWith("/")) {
                theUrl = hostName + theUrl;
            }
            else if (theUrl.StartsWith("../")) {
                while (theUrl.StartsWith("../")) {
                    pathLevel = ++pathLevel;
                    theUrl = theUrl.Remove(0, 3);
                }
                for (int i = 0; i < pathLevel; i++) {
                    BaseUrl = BaseUrl.Substring(0, BaseUrl.LastIndexOf("/", BaseUrl.Length - 2));
                }
                theUrl = BaseUrl + "/" + theUrl;
            }
            if (!theUrl.StartsWith("http://") && !theUrl.StartsWith("https://")) {
                theUrl = BaseUrl + "/" + theUrl;
            }
            return theUrl;
        }

        /// <summary>
        /// 获取连接
        /// </summary>
        /// <param name="pageStr">截取的字符串</param>
        /// <param name="strStart">开始字符串</param>
        /// <param name="strEnd">结束字符串</param>
        /// <returns>匹配导的所有连接 ArrayList类型</returns>
        public ArrayList GetArray(string pageStr, string strStart, string strEnd) {
            ArrayList linkArray = new ArrayList();
            int start = pageStr.IndexOf(strStart);
            if (strStart.Length == 0 || start < 0) {
                linkArray.Add("$StartFalse$");
                return linkArray;
            }
            int end = pageStr.IndexOf(strEnd);
            if (strEnd.Length == 0 || end < 0) {
                linkArray.Add("$EndFalse$");
                return linkArray;
            }
            Regex myRegex = new Regex(@"(" + strStart + ").+?(" + strEnd + ")", RegexOptions.IgnoreCase);
            MatchCollection matches = myRegex.Matches(pageStr);
            foreach (Match match in matches)
                linkArray.Add(match.ToString());
            if (linkArray.Count == 0) {
                linkArray.Add("$NoneLink$");
                return linkArray;
            }
            string TempStr = string.Empty;
            for (int i = 0; i < linkArray.Count; i++) {
                TempStr = linkArray[i].ToString();
                TempStr = TempStr.Replace(strStart, "");
                TempStr = TempStr.Replace(strEnd, "");
                linkArray[i] = (object)TempStr;
            }
            return linkArray;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pageStr"></param>
        /// <param name="SavePath"></param>
        /// <param name="CDir"></param>
        /// <param name="webUrl"></param>
        /// <param name="isSave"></param>
        /// <returns></returns>
        public ArrayList ReplaceSaveRemoteFile(string pageStr, string SavePath, string CDir, string webUrl, string isSave) {
            ArrayList replaceArray = new ArrayList();
            Regex imgReg = new Regex(@"<img.+?[^\>]>", RegexOptions.IgnoreCase);
            MatchCollection matches = imgReg.Matches(pageStr);
            string TempStr = string.Empty;
            string TitleImg = string.Empty;
            foreach (Match match in matches) {
                if (TempStr != string.Empty)
                    TempStr += "$Array$" + match.ToString();
                else
                    TempStr = match.ToString();
            }
            string[] TempArr = TempStr.Split(new string[] { "$Array$" }, StringSplitOptions.None);
            TempStr = string.Empty;
            imgReg = new Regex(@"src\s*=\s*.+?\.(gif|jpg|bmp|jpeg|psd|png|svg|dxf|wmf|tiff)", RegexOptions.IgnoreCase);
            for (int i = 0; i < TempArr.Length; i++) {
                matches = imgReg.Matches(TempArr[i]);
                foreach (Match match in matches) {
                    if (TempStr != string.Empty)
                        TempStr += "$Array$" + match.ToString();
                    else
                        TempStr = match.ToString();
                }
            }
            if (TempStr.Length > 0) {
                imgReg = new Regex(@"src\s*=\s*", RegexOptions.IgnoreCase);
                TempStr = imgReg.Replace(TempStr, "");
            }
            if (TempStr.Length == 0) {
                replaceArray.Add(pageStr);
                return replaceArray;
            }
            TempStr = TempStr.Replace("\"", "");
            TempStr = TempStr.Replace("'", "");
            TempStr = TempStr.Replace(" ", "");

            SavePath = SavePath + "/UserFiles/" + Easp.Fso.GetDateDir();
            if (!System.IO.Directory.Exists(SavePath))
                System.IO.Directory.CreateDirectory(SavePath);

            //去掉重复图片
            TempArr = TempStr.Split(new string[] { "$Array$" }, StringSplitOptions.None);
            TempStr = string.Empty;
            for (int i = 0; i < TempArr.Length; i++) {
                if (TempStr.IndexOf(TempArr[i]) == -1)
                    TempStr += "$Array$" + TempArr[i];
            }
            TempStr = TempStr.Substring(7);

            TempArr = TempStr.Split(new string[] { "$Array$" }, StringSplitOptions.None);
            TempStr = string.Empty;
            string ImageArr = string.Empty;
            for (int i = 0; i < TempArr.Length; i++) {
                imgReg = new Regex(TempArr[i]);
                string RemoteFileUrl = DefiniteUrl(TempArr[i], webUrl);
                if (isSave == "1") {
                    string fileType = RemoteFileUrl.Substring(RemoteFileUrl.LastIndexOf('.'));
                    string filename = string.Empty;
                    filename = Easp.Fso.GetDateFile();
                    filename += fileType;
                    if (SaveRemotePhoto(SavePath + "/" + filename, RemoteFileUrl))
                        RemoteFileUrl = CDir + "/UserFiles/" + Easp.Fso.GetDateDir() + "/" + filename;
                }
                pageStr = imgReg.Replace(pageStr, RemoteFileUrl);
                if (i == 0) {
                    TitleImg = RemoteFileUrl;
                    ImageArr = RemoteFileUrl;
                }
                else
                    ImageArr += "|||" + RemoteFileUrl;
            }
            replaceArray.Add(pageStr);
            replaceArray.Add(TitleImg);
            replaceArray.Add(ImageArr);
            return replaceArray;
        }

        /// <summary>
        /// 替换字符为远程的链接  比如 index.aspx 替换为http://www.qbzw.com/index.aspx
        /// </summary>
        /// <param name="PrimitiveUrl"></param>
        /// <param name="ConsultUrl"></param>
        /// <returns></returns>
        public string DefiniteUrl(string PrimitiveUrl, string ConsultUrl) {
            if (ConsultUrl.Substring(0, 7) != "http://")
                ConsultUrl = "http://" + ConsultUrl;
            ConsultUrl = ConsultUrl.Replace(@"\", "/");
            ConsultUrl = ConsultUrl.Replace("://", @":\\");
            PrimitiveUrl = PrimitiveUrl.Replace(@"\", "/");

            if (ConsultUrl.Substring(ConsultUrl.Length - 1) != "/") {
                if (ConsultUrl.IndexOf('/') > 0) {
                    if (ConsultUrl.Substring(ConsultUrl.LastIndexOf("/"), ConsultUrl.Length - ConsultUrl.LastIndexOf("/")).IndexOf('.') == -1)
                        ConsultUrl += "/";
                }
                else
                    ConsultUrl += "/";
            }
            string[] ConArray = ConsultUrl.Split('/');
            string returnStr = string.Empty;
            string[] PriArray;
            int pi = 0;
            if (PrimitiveUrl.Substring(0, 7) == "http://")
                returnStr = PrimitiveUrl.Replace("://", @":\\");
            else if (PrimitiveUrl.Substring(0, 1) == "/")
                returnStr = ConArray[0] + PrimitiveUrl;
            else if (PrimitiveUrl.Substring(0, 2) == "./") {
                PrimitiveUrl = PrimitiveUrl.Substring(PrimitiveUrl.Length - 2, 2);
                if (ConsultUrl.Substring(ConsultUrl.Length - 1) == "/")
                    returnStr = ConsultUrl + PrimitiveUrl;
                else
                    returnStr = ConsultUrl.Substring(0, ConsultUrl.LastIndexOf('/')) + PrimitiveUrl;
            }
            else if (PrimitiveUrl.Substring(0, 3) == "../") {
                while (PrimitiveUrl.Substring(0, 3) == "../") {
                    PrimitiveUrl = PrimitiveUrl.Substring(3);
                    pi++;
                }
                for (int i = 0; i < ConArray.Length - 1 - pi; i++) {
                    if (returnStr.Length > 0)
                        returnStr = returnStr + ConArray[i];
                    else
                        returnStr = ConArray[i];
                }
                returnStr = returnStr + PrimitiveUrl;
            }
            else {
                if (PrimitiveUrl.IndexOf('/') > -1) {
                    PriArray = PrimitiveUrl.Split('/');
                    if (PriArray[0].IndexOf('.') > -1) {
                        if (PrimitiveUrl.Substring(PrimitiveUrl.Length - 1) == "/")
                            returnStr = "http://" + PrimitiveUrl;
                        {
                            if (PriArray[PriArray.Length - 1].IndexOf('.') > -1)
                                returnStr = "http:\\" + PrimitiveUrl;
                            else
                                returnStr = "http:\\" + PrimitiveUrl + "/";
                        }
                    }
                    else {
                        if (ConsultUrl.Substring(ConsultUrl.Length - 1) == "/")
                            returnStr = ConsultUrl + PrimitiveUrl;
                        else
                            returnStr = ConsultUrl.Substring(0, ConsultUrl.LastIndexOf('/')) + PrimitiveUrl;
                    }
                }
                else {
                    if (PrimitiveUrl.IndexOf('.') > -1) {
                        string lastUrl = ConsultUrl;//.Substring(ConsultUrl.LastIndexOf('.'));
                        if (ConsultUrl.Substring(ConsultUrl.Length - 1) == "/") {
                            if (lastUrl == "com" || lastUrl == "cn" || lastUrl == "net" || lastUrl == "org")
                                returnStr = "http:\\" + PrimitiveUrl + "/";
                            else
                                returnStr = ConsultUrl + PrimitiveUrl;
                        }
                        else {
                            if (lastUrl == "com" || lastUrl == "cn" || lastUrl == "net" || lastUrl == "org")
                                returnStr = "http:\\" + PrimitiveUrl + "/";
                            else
                                returnStr = ConsultUrl.Substring(0, ConsultUrl.LastIndexOf('/')) + "/" + PrimitiveUrl;
                        }
                    }
                    else {
                        if (ConsultUrl.Substring(ConsultUrl.Length - 1) == "/")
                            returnStr = ConsultUrl + PrimitiveUrl + "/";
                        else
                            returnStr = ConsultUrl.Substring(0, ConsultUrl.LastIndexOf('/')) + "/" + PrimitiveUrl + "/";
                    }
                }
            }

            if (returnStr.Substring(0, 1) == "/")
                returnStr = returnStr.Substring(1);
            if (returnStr.Length > 0) {
                returnStr = returnStr.Replace("//", "/");
                returnStr = returnStr.Replace(@":\\", "://");
            }
            else
                returnStr = "$False$";
            return returnStr;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="RemoteFileUrl"></param>
        /// <returns></returns>
        public bool SaveRemotePhoto(string fileName, string RemoteFileUrl) {
            try {
                WebRequest request = WebRequest.Create(RemoteFileUrl);
                request.Timeout = 20000;
                Stream stream = request.GetResponse().GetResponseStream();
                Image getImage = Image.FromStream(stream);
                getImage.Save(fileName);
                return true;
            }
            catch (Exception) {
                return false;
            }
        }

        /// <summary>
        /// 移除制定 html标签代码
        /// </summary>
        /// <param name="ConStr"></param>
        /// <param name="TagName"></param>
        /// <param name="FType"></param>
        /// <returns></returns>
        public string ScriptHtml(string ConStr, string TagName, int FType) {
            Regex myReg;
            switch (FType) {
                case 1:
                    myReg = new Regex("<" + TagName + "([^>])*>", RegexOptions.IgnoreCase);
                    ConStr = myReg.Replace(ConStr, "");
                    break;
                case 2:
                    myReg = new Regex("<" + TagName + "([^>])*>.*?</" + TagName + "([^>])*>", RegexOptions.IgnoreCase);
                    ConStr = myReg.Replace(ConStr, "");
                    break;
                case 3:
                    myReg = new Regex("<" + TagName + "([^>])*>", RegexOptions.IgnoreCase);
                    ConStr = myReg.Replace(ConStr, "");
                    myReg = new Regex("</" + TagName + "([^>])*>", RegexOptions.IgnoreCase);
                    ConStr = myReg.Replace(ConStr, "");
                    break;
            }
            return ConStr;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ConStr"></param>
        /// <returns></returns>
        public string NoHtml(string ConStr) {
            Regex myReg = new Regex(@"(\<.[^\<]*\>)", RegexOptions.IgnoreCase);
            ConStr = myReg.Replace(ConStr, "");
            myReg = new Regex(@"(\<\/[^\<]*\>)", RegexOptions.IgnoreCase);
            ConStr = myReg.Replace(ConStr, "");
            return ConStr;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pageStr"></param>
        /// <param name="strStart"></param>
        /// <param name="strEnd"></param>
        /// <returns></returns>
        public string GetPaing(string pageStr, string strStart, string strEnd) {
            int end = pageStr.IndexOf(strEnd);
            if (strEnd.Length == 0 || end < 0)
                return "$EndFalse$";
            pageStr = pageStr.Substring(0, end);
            int start = pageStr.LastIndexOf(strStart);
            if (strStart.Length == 0 || start < 0 || start > end)
                return "$StartFalse$";
            pageStr = pageStr.Substring(start + strStart.Length);
            pageStr = pageStr.Replace("\"", "");
            pageStr = pageStr.Replace("'", "");
            pageStr = pageStr.Replace(" ", "");
            pageStr = pageStr.Trim();
            return pageStr;
        }



        #region  分割采集
        /// <summary>
        /// 分割采集Url
        /// </summary>
        /// <param name="Url"></param>
        /// <returns></returns>
        public List<string> SplitWebUrl(string Url) {
            List<string> Urls = new List<string>();
            try {
                if (!Regex.IsMatch(Url, "{.*}")) {
                    Urls.Add(Url);
                    return Urls;
                }
                //判断是否存在
                while (Regex.IsMatch(Url, "{.*}")) {
                    //提取参数内容
                    string strMatch = "(?<={)[^}]*(?=})";
                    Match s = Regex.Match(Url, strMatch, RegexOptions.IgnoreCase);
                    string UrlPara = s.Groups[0].Value;
                    List<string> g_Url = getListUrl(UrlPara, Url);
                    foreach (string str in g_Url) {
                        string temp = Url;
                        Urls.Add(temp.Replace("{" + UrlPara + "}", str));
                    }
                    Url = Url.Replace("{" + UrlPara + "}", "");
                }
            }
            catch (Exception) {
                //log.Error("分割采集Url失败!", ex);
            }
            return Urls;
        }
        /// <summary>
        /// 获取Url参数
        /// </summary>
        /// <param name="dicPre"></param>
        /// <param name="Url"></param>
        /// <returns></returns>
        private List<string> getListUrl(string dicPre, string Url) {
            List<string> list_Para = new List<string>();
            Regex re;
            MatchCollection aa;
            int step;
            int startI;
            int endI;
            int i = 0;
            try {
                switch (dicPre.Substring(0, dicPre.IndexOf(":"))) {
                    case "Num":
                        re = new Regex("([\\-\\d]+)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                        aa = re.Matches(dicPre);
                        startI = int.Parse(aa[0].Groups[0].Value.ToString());
                        endI = int.Parse(aa[1].Groups[0].Value.ToString());
                        step = int.Parse(aa[2].Groups[0].Value.ToString());
                        if (step > 0) {
                            for (i = startI; i <= endI; i = i + step) {
                                list_Para.Add(i.ToString());
                            }
                        }
                        else {
                            for (i = startI; i >= endI; i = i + step) {
                                list_Para.Add(i.ToString());
                            }
                        }
                        break;

                    case "Letter":
                        startI = getAsc(dicPre.Substring(dicPre.IndexOf(":") + 1, 1));
                        endI = getAsc(dicPre.Substring(dicPre.IndexOf(",") + 1, 1));
                        if (startI > endI) {
                            step = -1;
                        }
                        else {
                            step = 1;
                        }

                        for (i = startI; i <= endI; i = i + step) {
                            char s;
                            s = Convert.ToChar(i);
                            list_Para.Add(s.ToString());
                        }
                        break;
                }
            }
            catch (Exception) {
                //log.Error("分割采集Url失败!", ex);
            }
            return list_Para;
        }

        private int getAsc(string s) {
            byte[] array = new byte[1];
            array = System.Text.Encoding.ASCII.GetBytes(s);
            int asciicode = (int)(array[0]);
            return asciicode;
        }
        #endregion

        /// <summary>
        /// 正则表达式标签替换
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public string ParseCollectionStrings(string s) {
            string[] chars = "\\,^,$,{,[,.,(,*,+,?,!,#,|".Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < chars.Length; i++) {
                s = s.Replace(chars[i], "\\" + chars[i]);
            }
            s = Regex.Replace(s, @"\s+", "\\s+");
            return s;
        }

    }
}